﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

using DTO;
using Model;

namespace DataService
{
    public class DeviceService : BaseService
    {
        private DeviceModel model = new DeviceModel();

        public DeviceService()
        {
            model =  new DeviceModel();
        }

        private IList<Device> ListDevice(DataTable dt)
        {
            IList<Device> devices = new List<Device>();
            if (dt != null)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    Device device = new Device(BaseModel.GetIntFieldValue(dr, "RequestAutoId"));

                    device.user = new User();
                    device.user.Username = BaseModel.GetStringFieldValue(dr, "Username");

                    device.user.Customer = new Customer();
                    device.user.Customer.Code = BaseModel.GetStringFieldValue(dr, "AccountName");

                    device.Plan = new Device.PlanType();
                    device.Plan.Name = BaseModel.GetStringFieldValue(dr, "PlanName");
                    device.Plan.CPUs = BaseModel.GetStringFieldValue(dr, "CPU");
                    device.Plan.RAM = BaseModel.GetStringFieldValue(dr, "Ram");
                    device.Plan.DiskQuota = BaseModel.GetStringFieldValue(dr, "DistSpace");

                    device.OS = new Device.OperatingSystem();
                    device.OS.Name = BaseModel.GetStringFieldValue(dr, "WindowName");

                    device.RequestDate = BaseModel.GetDateTimeFieldValue(dr, "RequestDate");
                    device.RequestStatus = BaseModel.GetIntFieldValue(dr, "RequestStatusId");
                    device.IsCustom = BaseModel.GetBooleanFieldValue(dr, "IsCustom");
                    device.RequestStatusName = BaseModel.GetStringFieldValue(dr, "Status");

                    devices.Add(device);
                }

            }
            return devices;
        }

        public IList<Device> GetListRequestDevice()
        {            
            DataTable dt = model.GetListRequestDevice();
            IList<Device> devices =ListDevice(dt);
            return devices;
        }

        public IList<Device> GetListRequestDeviceByAll(string AccountName, string UserName, DateTime? RequestFromDate, DateTime? RequestToDate, int WindowId, int RequestStatusId)
        {
            DataTable dt = model.GetListRequestDeviceByAll(AccountName, UserName, RequestFromDate, RequestToDate, WindowId, RequestStatusId);
            IList<Device> devices = ListDevice(dt);
            return devices;
        }

        public Device GetListRequestByRequestId(int RequestDeviceId)
        {
            DataTable dt = model.GetListRequestByRequestId(RequestDeviceId);
            
            if(dt!=null && dt.Rows.Count>0)
            {
                DataRow dr = dt.Rows[0];
                Device device = new Device(BaseModel.GetIntFieldValue(dr, "RequestDeviceId"));
                device.Plan = new Device.PlanType();
                device.Plan.CPUs = BaseModel.GetStringFieldValue(dr, "CPUId");
                device.Plan.RAM = BaseModel.GetStringFieldValue(dr, "RamId");
                device.Plan.DiskQuota =BaseModel.GetStringFieldValue(dr, "DistSpaceId");
                device.OS = new Device.OperatingSystem(BaseModel.GetIntFieldValue(dr, "WindowId"));
                return device;
            }
            
            return null;
        }

        public DataTable GetRequestStatus()
        {
            DataTable dt=model.GetRequestStatus();
            DataRow  dr=dt.NewRow();
            dr["RequestStatusId"] = 0;
            dr["RequestStatusName"] = "All";
            dt.Rows.InsertAt(dr, 0);
            return dt;
        }

        public IList<Device.PlanType> GetListPlansTemplate()
        {
            DataTable dt = model.GetListPlansTemplate();
            if (dt != null)
            {
                if (dt.Rows.Count > 0)
                {
                    IList<Device.PlanType> plans = new List<Device.PlanType>();
                    foreach (DataRow row in dt.Rows)
                    {
                        Device.PlanType plan = new Device.PlanType(DeviceModel.GetIntFieldValue(row, DeviceModel.AUTO_ID_PLAN));
                        plan.Name = DeviceModel.GetStringFieldValue(row, DeviceModel.PLAN_NAME);
                        plan.RAM = DeviceModel.GetStringFieldValue(row, DeviceModel.PLAN_RAM);
                        plan.CPUs = DeviceModel.GetStringFieldValue(row, DeviceModel.PLAN_VCPU);
                        plan.Price = DeviceModel.GetStringFieldValue(row, DeviceModel.PLAN_MONTHLYFEE);
                        plan.DiskQuota = DeviceModel.GetStringFieldValue(row, DeviceModel.PLAN_DIST_QUOTA);
                        plan.Bandwidth = DeviceModel.GetStringFieldValue(row, DeviceModel.PLAN_BANDWIDTH);
                        plan.MonthlyFee = DeviceModel.GetFloatFieldValue(row, DeviceModel.PLAN_MONTHLYFEE);
                        plan.SpecificationId = DeviceModel.GetIntFieldValue(row, DeviceModel.PLAN_SPECIFICATION_ID);
                        
                        plans.Add(plan);
                    }
                    return plans;
                }
            }
            return null;
        }

        public IList<Device.CPUs> GetListCPU()
        {
            DataTable dt = model.GetListCPU();
            if (dt != null)
            {
                if (dt.Rows.Count > 0)
                {
                    IList<Device.CPUs> cpus = new List<Device.CPUs>();
                    foreach (DataRow row in dt.Rows)
                    {
                        Device.CPUs cpu = new Device.CPUs(DeviceModel.GetIntFieldValue(row, DeviceModel.CPU_ID));
                        cpu.Price = DeviceModel.GetStringFieldValue(row, DeviceModel.CPU_PRICE);
                        cpu.Name = DeviceModel.GetStringFieldValue(row, DeviceModel.CPU_vCPU);
                        cpu.Specification = DeviceModel.GetStringFieldValue(row, DeviceModel.CPU_SPECIFICATION);
                        cpu.Details = cpu.ToString();
                        cpus.Add(cpu);
                    }
                    return cpus;
                }
            }
            return null;
        }

        public IList<Device.DiskSpace> GetListDiskPlace()
        {
            DataTable dt = model.GetListDiskSpace();
            if (dt != null)
            {
                if (dt.Rows.Count > 0)
                {
                    IList<Device.DiskSpace> diskplaces = new List<Device.DiskSpace>();
                    foreach (DataRow row in dt.Rows)
                    {
                        Device.DiskSpace diskplace = new Device.DiskSpace(DeviceModel.GetIntFieldValue(row, DeviceModel.DISKSPACE_ID));
                        diskplace.Price = DeviceModel.GetStringFieldValue(row, DeviceModel.DISKSPACE_PRICE);
                        diskplace.Name = DeviceModel.GetStringFieldValue(row, DeviceModel.DISKSPACE);
                        diskplace.Specification = DeviceModel.GetStringFieldValue(row, DeviceModel.DISKSPACE_SPECIFICATION);
                        diskplace.Details = diskplace.ToString();
                        diskplaces.Add(diskplace);
                    }
                    return diskplaces;
                }
            }
            return null;
        }

        public IList<Device.Specification> GetListSpecifications()
        {
            DataTable dt = model.GetListSpecification();
            if (dt != null)
            {
                if (dt.Rows.Count > 0)
                {
                    IList<Device.Specification> Specifications = new List<Device.Specification>();
                    foreach (DataRow row in dt.Rows)
                    {
                        Device.Specification Specification = new Device.Specification(DeviceModel.GetIntFieldValue(row, DeviceModel.SPECIFICATION_ID));
                        Specification.Name= DeviceModel.GetStringFieldValue(row, DeviceModel.SPECIFICATION_NAME);
                        Specifications.Add(Specification);
                    }
                    return Specifications;
                }
            }
            return null;
        }

        public IList<Device.Memory> GetListMemory()
        {
            DataTable dt = model.GetListMemory();
            if (dt != null)
            {
                if (dt.Rows.Count > 0)
                {
                    IList<Device.Memory> memorys = new List<Device.Memory>();
                    foreach (DataRow row in dt.Rows)
                    {
                        Device.Memory memory = new Device.Memory(DeviceModel.GetIntFieldValue(row, DeviceModel.MEMORY_ID));
                        memory.Price = DeviceModel.GetStringFieldValue(row, DeviceModel.MEMORY_PRICE);
                        memory.Name = DeviceModel.GetStringFieldValue(row, DeviceModel.MEMORY);
                        memory.Specification = DeviceModel.GetStringFieldValue(row, DeviceModel.MEMORY_SPECIFICATION);
                        memory.Details = memory.ToString();
                        memorys.Add(memory);
                    }
                    return memorys;
                }
            }
            return null;
        }

        public IList<Device> GetDevicesDependFirewallByAccountIdAndFirewallId(int customerId, int firewallId = -1)
        {
            DataTable table = model.GetDevicesDependFirewallByAccountIdAndFirewallId(customerId, firewallId);

            IList<Device> devices = new List<Device>();

            if (table != null && table.Rows.Count > 0)
            {
                foreach (DataRow row in table.Rows)
                {
                    devices.Add(new Device(BaseModel.GetIntFieldValue(row, "DeviceId"))
                    {
                        Name = BaseModel.GetStringFieldValue(row, "DeviceName"),
                        FriendlyName = BaseModel.GetStringFieldValue(row, "DeviceFriendlyName"),
                        IP = BaseModel.GetStringFieldValue(row, "DeviceIP"),
                        Fee = BaseModel.GetDoubleFieldValue(row, "DeviceFee"),
                        CPU = BaseModel.GetStringFieldValue(row, "CPU"),
                        RAM = BaseModel.GetStringFieldValue(row, "RAM"),
                        DiskQuota = BaseModel.GetStringFieldValue(row, "DiskQuota"),
                        Bandwidth = BaseModel.GetStringFieldValue(row, "Bandwidth"),
                        IsCheck = BaseModel.GetBooleanFieldValue(row, "IsCheck"),
                        OS = new Device.OperatingSystem(BaseModel.GetIntFieldValue(row, "OSId"))
                        {
                            Name = BaseModel.GetStringFieldValue(row, "OSName"),
                        },
                        Firewall = new Firewall(BaseModel.GetIntFieldValue(row, "FirewallId"))
                        {
                            Code = BaseModel.GetStringFieldValue(row, "FirewallNo"),
                            Name = BaseModel.GetStringFieldValue(row, "FirewallName"),
                            FriendlyName = BaseModel.GetStringFieldValue(row, "FirewallFriendlyName"),
                            IP = BaseModel.GetStringFieldValue(row, "FirewallIP"),
                            Fee = BaseModel.GetDoubleFieldValue(row, "FirewallFee")
                        }
                    });
                }
            }
            return devices;
        }

        public IList<Device> GetDevices ( int customerId, int firewallId = -1)
        {
            DataTable table = null;

            if (firewallId <= 0)
                table = model.GetDevicesByCustomerId(customerId);
            else
                table = model.GetDevicesByCustomerIdAndFirewallId(customerId, firewallId);

            IList<Device> devices = new List<Device>();

            if ( table != null && table.Rows.Count > 0 )
            {
                foreach ( DataRow row in table.Rows )
                {
                    devices.Add(new Device(BaseModel.GetIntFieldValue(row, "DeviceId"))
                    {
                        Name = BaseModel.GetStringFieldValue(row, "DeviceName"),
                        FriendlyName = BaseModel.GetStringFieldValue(row, "DeviceFriendlyName"),
                        IP = BaseModel.GetStringFieldValue(row, "DeviceIP"),
                        Fee = BaseModel.GetDoubleFieldValue(row, "DeviceFee"),
                        CPU = BaseModel.GetStringFieldValue(row, "CPU"),
                        RAM = BaseModel.GetStringFieldValue(row, "RAM"),
                        DiskQuota = BaseModel.GetStringFieldValue(row, "DiskQuota"),
                        Bandwidth = BaseModel.GetStringFieldValue(row, "Bandwidth"),
                        IsCheck=BaseModel.GetBooleanFieldValue(row,"IsCheck"),
                        OS = new Device.OperatingSystem(BaseModel.GetIntFieldValue(row, "OSId"))
                        {
                            Name = BaseModel.GetStringFieldValue(row, "OSName"),
                        },
                        Firewall = new Firewall(BaseModel.GetIntFieldValue(row, "FirewallId"))
                        {
                            Code = BaseModel.GetStringFieldValue(row, "FirewallNo"),
                            Name = BaseModel.GetStringFieldValue(row, "FirewallName"),
                            FriendlyName = BaseModel.GetStringFieldValue(row, "FirewallFriendlyName"),
                            IP = BaseModel.GetStringFieldValue(row, "FirewallIP"),
                            Fee = BaseModel.GetDoubleFieldValue(row, "FirewallFee")
                        }
                    });
                }
            }
            return devices;
        }

        public IList<Device> GetListDeviceByAccountId(int AccountId)
        {
            DataTable dt = model.GetListDeviceByAccountId(AccountId);
            IList<Device> devices = new List<Device>();
            if (dt != null && dt.Rows.Count > 0)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    Device device = new Device(DeviceModel.GetIntFieldValue(dr, "DeviceId"));
                    device.Name = DeviceModel.GetStringFieldValue(dr, "DeviceName");
                    device.DeviceType = DeviceModel.GetStringFieldValue(dr, "DeviceType");
                    device.FriendlyName = DeviceModel.GetStringFieldValue(dr, "FriendlyName");

                    device.OS = new Device.OperatingSystem();
                    device.OS.Name = DeviceModel.GetStringFieldValue(dr, "OptionName");

                    device.Plan = new Device.PlanType();
                    device.Plan.CPUs = DeviceModel.GetStringFieldValue(dr, "vCPU");
                    device.Plan.RAM = DeviceModel.GetStringFieldValue(dr, "Ram");
                    device.FriendlyName = DeviceModel.GetStringFieldValue(dr, "FriendlyName");
                    devices.Add(device);
                }
            }
            return devices;
        }

        public IList<Device> GetListDeviceByAccountIdAndDeviceId(int AccountId, int DeviceId, string filter,bool Isfirewall)
        {
            DataTable dt = new DataTable();
            if (!Isfirewall)
            {
                dt = model.GetListDeviceByAccountIdAndDeviceId(AccountId, DeviceId);
                dt.DefaultView.RowFilter = "DeviceType='" + filter + "'";
            }
            else
            {
                dt = model.GetListDeviceByAccountId(AccountId);
                dt.DefaultView.RowFilter = "DeviceIdType <>'" + filter + "'";
            }
            DataView dv =dt.DefaultView;
            IList<Device> devices = new List<Device>();
            foreach (DataRowView dr in dv)
            {
                Device device = new Device(DeviceModel.GetIntFieldValue(dr, "DeviceId"));
                device.Name = DeviceModel.GetStringFieldValue(dr, "DeviceName");
                device.DeviceType = DeviceModel.GetStringFieldValue(dr, "DeviceType");
                device.IP = DeviceModel.GetStringFieldValue(dr, "IPAddress");
                
                device.OS = new Device.OperatingSystem();
                device.OS.Name = DeviceModel.GetStringFieldValue(dr, "OptionName");

                device.Plan = new Device.PlanType();
                device.Plan.CPUs = DeviceModel.GetStringFieldValue(dr, "vCPU");
                device.Plan.RAM = DeviceModel.GetStringFieldValue(dr, "Ram");

                devices.Add(device);
            }
            return devices;
        }

        public IList<Device> GetListDeviceByAccountIdAndFirewallId(int AccountId, int FirewalId)
        {
            DataTable dt = model.GetListDeviceByAccountIdAndFirewallId(AccountId, FirewalId);
            DataView dv = dt.DefaultView;
            IList<Device> devices = new List<Device>();
            if (dt != null && dt.Rows.Count > 0)
            {
                foreach (DataRowView dr in dv)
                {
                    Device device = new Device(DeviceModel.GetIntFieldValue(dr, "DeviceId"));
                    device.Name = DeviceModel.GetStringFieldValue(dr, "Name");
                    device.DeviceType = DeviceModel.GetStringFieldValue(dr, "DeviceType");
                    device.FriendlyName = DeviceModel.GetStringFieldValue(dr, "FriendlyName");
                    device.IP = DeviceModel.GetStringFieldValue(dr, "IPAddress");
                    devices.Add(device);
                }
            }
            return devices;
        }

        public IList<Firewall> GetFirewallsByCustomerId ( int customerId )
        {
            IList<Firewall> firewalls = new List<Firewall>();
            DataTable table = ( new DeviceModel() ).GetFirewallsByCustomerId(customerId);

            foreach ( DataRow row in table.Rows )
            {
                firewalls.Add(new Firewall(BaseModel.GetIntFieldValue(row, "AutoId"))
                {
                    Code = BaseModel.GetStringFieldValue(row, "FirewallNo"),
                    Name = BaseModel.GetStringFieldValue(row, "FirewallName"),
                    IP = BaseModel.GetStringFieldValue(row, "IPAddress"),
                    Fee=BaseModel.GetDoubleFieldValue(row,"Fee")
                });
            }

            return firewalls;
        }

        public void UpdateDeviceFriendlyNameByDeviceId(int DeviceId, string FriendlyName, string Notes)
        {
            DataRow row = model.UpdateDeviceFriendlyNameByDeviceId(DeviceId, FriendlyName, Notes);
        }

        public IList<Firewall> GetFirewalls ( int customerId )
        {
            DataTable table = model.GetFirewallsByCustomerId(customerId);
            IList<Firewall> list = new List<Firewall>();
            if ( table != null && table.Rows.Count > 0 )
            {
                foreach ( DataRow row in table.Rows )
                {
                    list.Add(new Firewall(BaseModel.GetIntFieldValue(row, "AutoId"))
                    {
                        Code = BaseModel.GetStringFieldValue(row, "FirewallNo"),
                        Name = BaseModel.GetStringFieldValue(row, "FirewallName"),
                        IP = BaseModel.GetStringFieldValue(row, "IPAddress"),
                        Fee = BaseModel.GetDoubleFieldValue(row, "Fee"),
                        RentFromDate = BaseModel.GetDateTimeFieldValue(row, "EffFromDate"),
                        RentToDate = BaseModel.GetDateTimeFieldValue(row, "EffToDate")
                    });
                }
            }
            return list;
        }

        public Device GetDevice ( int id )
        {
            DataRow row = model.GetDevice(id);
            if ( row != null )
            {
                return new Device(id)
                {
                    Name = BaseModel.GetStringFieldValue(row, "Name"),
                    IP = BaseModel.GetStringFieldValue(row, "IPAddress"),
                    Fee = BaseModel.GetDoubleFieldValue(row, "Fee"),
                    RAM = BaseModel.GetStringFieldValue(row, "RAM"),
                    CPU = BaseModel.GetStringFieldValue(row, "CPU"),
                    DiskQuota = BaseModel.GetStringFieldValue(row, "DiskQuota"),
                    Bandwidth = BaseModel.GetStringFieldValue(row, "Bandwidth"),
                    RentFromDate = BaseModel.GetDateTimeFieldValue(row, "EffFromDate"),
                    RentToDate = BaseModel.GetDateTimeFieldValue(row, "EffToDate"),
                    OS = new Device.OperatingSystem(BaseModel.GetIntFieldValue(row, "OSId"))
                    {
                        Name = BaseModel.GetStringFieldValue(row, "OSName")
                    }
                };
            }
            return null;
        }

        public Firewall GetFirewall ( int id )
        {
            DataRow row = model.GetFirewall(id);
            if (row != null)
            {
                return new Firewall(id)
                {
                    Code = BaseModel.GetStringFieldValue(row, "FirewallNo"),
                    Name = BaseModel.GetStringFieldValue(row, "FirewallName"),
                    IP = BaseModel.GetStringFieldValue(row, "IPAddress"),
                    Fee = BaseModel.GetDoubleFieldValue(row, "Fee"),
                    RentFromDate = BaseModel.GetDateTimeFieldValue(row, "EffFromDate"),
                    RentToDate = BaseModel.GetDateTimeFieldValue(row, "EffToDate")
                };
            }
            return null;
        }

        public IList<Firewall> GetFirewallByFirewallId(int Id)
        {

            DataTable dt = model.GetFirewallByFirewallId(Id);
            IList<Firewall> firewalls = new List<Firewall>();
            if (dt != null && dt.Rows.Count > 0)
            {
                foreach (DataRow row in dt.Rows)
                {
                    Firewall firewall = new Firewall();
                    firewall.Code = BaseModel.GetStringFieldValue(row, "FirewallNo");
                    firewall.Name = BaseModel.GetStringFieldValue(row, "FirewallName");
                    firewall.IP = BaseModel.GetStringFieldValue(row, "IPAddress");
                    firewalls.Add(firewall);
                }

            }
            return firewalls;
        }
        public IList<Device.OperatingSystem> GetListOS()
        {
            DataTable dt = model.GetListOS();
            if (dt != null)
            {
                if (dt.Rows.Count > 0)
                {
                    IList<Device.OperatingSystem> OSs = new List<Device.OperatingSystem>();
                    foreach (DataRow row in dt.Rows)
                    {
                        Device.OperatingSystem os = new Device.OperatingSystem(DeviceModel.GetIntFieldValue(row, DeviceModel.AUTO_ID_OS));
                        os.Name = DeviceModel.GetStringFieldValue(row, DeviceModel.NAME_OS);
                        OSs.Add(os);
                    }
                    return OSs;
                }
            }
            return null;
        }

        public void AddRequestCustomer(int UserId, int PlanId, int CpuId, int RamId, int DiskQuoteId,int OsId , bool IsCustom)
        {
            DataTable dt = model.AddRequestCustomer(UserId, CpuId, RamId, DiskQuoteId, OsId, PlanId, IsCustom);
        }

        public Device SaveDevice ( Device device )
        {
            using ( DeviceModel model = new DeviceModel() )
            {
                device.Id = model.SaveDevice(device.Customer.Id, device.Id, device.Name, device.CPU, device.RAM, device.DiskQuota, device.Bandwidth, device.OS.Id, device.IP, device.Fee, device.RentFromDate, device.RentToDate);
            }

            return device;
        }

        public Firewall SaveFirewall ( Firewall firewall )
        {
            using ( DeviceModel model = new DeviceModel() )
            {
                firewall.Id = model.SaveFirewall(firewall.Customer.Id, firewall.Id, firewall.Code, firewall.Name, firewall.IP, firewall.Fee, firewall.RentFromDate, firewall.RentToDate);
            }

            return firewall;
        }

        public void BindDevicesToFirewall ( Firewall firewall, IList<Device> devices )
        {
            if ( devices.Count > 0 )
            {
                string deviceIds = "";
                foreach ( Device device in devices )
                {
                    deviceIds  += "," + device.Id.ToString();
                }

                if (deviceIds != "")
                {
                    deviceIds = deviceIds.Substring(1);
                    using (DeviceModel model = new DeviceModel())
                    {
                        model.BindDevicesToFirewall(firewall.Id, deviceIds);
                    }
                }
            }
        }

        public void RemoveDevicesFromFirewall ( Firewall firewall, IList<Device> devices )
        {
            if ( devices.Count > 0 )
            {
                string deviceIds = "";
                foreach ( Device device in devices )
                {
                    deviceIds += "," + device.Id.ToString();
                }

                if (deviceIds != "")
                {
                    deviceIds = deviceIds.Substring(1);
                    using (DeviceModel model = new DeviceModel())
                    {
                        model.RemoveDevicesFromFirewall(firewall.Id, deviceIds);
                    }
                }
            }
        }

        public void DeleteDevice ( int id )
        {
            model.DeleteDevice(id);
        }

        public void DeleteFirewall ( int firewallId )
        {
            model.DeleteFirewall(firewallId);
        }

        public void DeleteRequestDevice(int RequestDeviceId)
        {
            model.DeleteRequestDevice(RequestDeviceId);
        }

        public void UpdateRequestDevice(int RequestDeviceId, int CPUId, int RAMId, int DistSpaceId, int OSId, string Bandwidth)
        {
            model.UpdateRequestDevice(RequestDeviceId, CPUId, RAMId, DistSpaceId, OSId, Bandwidth);
        }

        public void UpdateRequestDeviceStatus(int RequestDeviceId, int RequestStatusId)
        {
            model.UpdateRequestDeviceStatus( RequestDeviceId,  RequestStatusId);
        }
    }
}
